/*
 *      EcouteurActionBouton.java
 *      
 *      Copyright 2011 Jean Clément Nigues <jeanclement@P5E3deluxe>
 *      
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 *      
 *      
 */
/**
 * @author Jean Clément NIGUES
 * @version 1.0
 *
 * <BR>1ère année
 * <BR>IUT à Vannes, Département Informatique
 * <BR>Année Universitaire : 2010/2011
 *
 * Cette classe gère les cliques sur les boutons.
 */
package pda.agenda.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.*;
import javax.swing.*;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.ArrayList;
import java.util.Iterator;

import pda.agenda.datas.*;
import pda.agenda.ihm.*;
import pda.agenda.Agenda;

public class EcouteurActionBouton implements ActionListener {
	
	public void actionPerformed(ActionEvent e) {

		Object src = e.getSource();
		// Clique sur le bouton "Mois suivant" ou "Mois Précédant" ou "Année Suivante" ou "Année précédante" ou sur "Un jour du mois"
		if(src == Agenda.view.getAgendaViewMois().getBoutonMoisPrecedant() || src == Agenda.view.getAgendaViewMois().getBoutonMoisSuivant() || Agenda.view.getAgendaViewMois().estUnBoutonJourneeDansMois(src) || src == Agenda.view.getAgendaViewMois().getBoutonAnneePrecedante() || src == Agenda.view.getAgendaViewMois().getBoutonAnneeSuivante()) {
			// Recupère le mois courant et l'année courante
			int anneeCourante = Integer.parseInt(Agenda.view.getAgendaViewMois().getLabelAnneeCourante().getText());
			int moisCourant = Agenda.view.getNumeroMois(Agenda.view.getAgendaViewMois().getLabelMoisCourant().getText());

			// Mois précédant
			if(src == Agenda.view.getAgendaViewMois().getBoutonMoisPrecedant()) {
				this.reactionClicMoisPrecedant(moisCourant,anneeCourante);
			// Mois suivant
			} else if(src == Agenda.view.getAgendaViewMois().getBoutonMoisSuivant()) {
				this.reactionClicMoisSuivant(moisCourant,anneeCourante);
			// Année suivante
			} else if(src == Agenda.view.getAgendaViewMois().getBoutonAnneeSuivante()) {
				this.reactionClicAnneeSuivante(moisCourant,anneeCourante);
			// Année précédante
			} else if(src == Agenda.view.getAgendaViewMois().getBoutonAnneePrecedante()) {
				this.reactionClicAnneePrecedante(moisCourant,anneeCourante);
			// Clique sur un jour, dans un mois.
			} else if(Agenda.view.getAgendaViewMois().estUnBoutonJourneeDansMois(src)) {
				// La couleur du texte est grisé, on change de mois.
				int jourCourant = Integer.parseInt(Agenda.view.getAgendaViewMois().getUnBoutonJourneeDansMois(src).getText());
				if(Color.GRAY == Agenda.view.getAgendaViewMois().getUnBoutonJourneeDansMois(src).getForeground()) {
					// C'est le mois précédant
					if(jourCourant > 15) {
						if(moisCourant-1 < 0) {
							moisCourant = 11;
							anneeCourante = anneeCourante-1;
						} else {
							moisCourant = moisCourant-1;
						}
					// Ou bien, le mois suivant
					} else {
						if(moisCourant+1 > 11) {
							moisCourant = 0;
							anneeCourante = anneeCourante+1;
						} else {
							moisCourant = moisCourant+1;
						}
					}
				}

				this.reactionClicJourDUnMois(jourCourant, moisCourant, anneeCourante);
			}
		// Clique sur le bouton "Jour suivant" ou "Jour Précédant"
		} else if(src == Agenda.view.getAgendaViewJour().getBoutonJourPrecedant() || src == Agenda.view.getAgendaViewJour().getBoutonJourSuivant()) {
			// Recupère la date courante (jour, mois, année)
			String[] date = Agenda.view.getAgendaViewJour().getLabelJourCourant().getText().split(" ");
			// date[0] = Nom du jour (Lundi, Mardi..)
			// dateCourante[0] = jour, [1] = mois, [2] = année
			String[] dateCourante = date[1].split("/");

			int jourCourant = Integer.parseInt(dateCourante[0]);
			int moisCourant = Integer.parseInt(dateCourante[1]);
			int anneeCourante = Integer.parseInt(dateCourante[2]);

			// Jour précédant
			if(src == Agenda.view.getAgendaViewJour().getBoutonJourPrecedant()) {
				this.reactionClicJourPrecedant(jourCourant, moisCourant, anneeCourante);
			// Jour suivant
			} else if(src == Agenda.view.getAgendaViewJour().getBoutonJourSuivant()) {
				this.reactionClicJourSuivant(jourCourant, moisCourant, anneeCourante);
			// Clique sur une activité
			}
		} else if(src == Agenda.view.getAgendaViewSemaine().getBoutonSemainePrecedante() || src == Agenda.view.getAgendaViewSemaine().getBoutonSemaineSuivante()) {

			// Recupère le numéro de la semaine courante et l'année courante
			String dateCourante[] = Agenda.view.getAgendaViewSemaine().getLabelSemaineCourante().getText().split(" ");
			int semaineCourante = Integer.parseInt(dateCourante[0].replaceAll("(er|ème)",""));
			int anneeCourante = Integer.parseInt(dateCourante[4]);

			if(src == Agenda.view.getAgendaViewSemaine().getBoutonSemainePrecedante()) {
				this.reactionClicSemainePrecedante(semaineCourante, anneeCourante);
			} else if(src == Agenda.view.getAgendaViewSemaine().getBoutonSemaineSuivante()) {
				this.reactionClicSemaineSuivante(semaineCourante, anneeCourante);
			}
		} else {
			System.out.println("[DEBUG] Source inconnue");
		}
	}

	/**
	 * Affiche l'année qui précède.
	 * @param moisCourant Le mois sur lequel nous sommes
	 * @param anneeCourante L'année sur laquelle nous sommes
	*/
	private void reactionClicAnneePrecedante(int moisCourant, int anneeCourante) {
		anneeCourante = anneeCourante-1;
		Agenda.view.creerListeJoursDuMois(moisCourant,anneeCourante);
	}

	/**
	 * Affiche l'année qui suit.
	 * @param moisCourant Le mois sur lequel nous sommes
	 * @param anneeCourante L'année sur laquelle nous sommes
	*/
	private void reactionClicAnneeSuivante(int moisCourant, int anneeCourante) {
		anneeCourante = anneeCourante+1;
		Agenda.view.creerListeJoursDuMois(moisCourant,anneeCourante);
	}

	/**
	 * Affiche le mois qui précède.
	 * @param moisCourant Le mois sur lequel nous sommes
	 * @param anneeCourante L'année sur laquelle nous sommes
	*/
	private void reactionClicMoisPrecedant(int moisCourant, int anneeCourante) {
		if(moisCourant-1 < 0) {
			moisCourant = 11;
			anneeCourante = anneeCourante-1;
		} else {
			moisCourant = moisCourant-1;
		}
		Agenda.view.creerListeJoursDuMois(moisCourant,anneeCourante);
	}

	/**
	 * Affiche le mois qui suit.
	 * @param moisCourant Le mois sur lequel nous sommes
	 * @param anneeCourante L'année sur laquelle nous sommes
	*/
	private void reactionClicMoisSuivant(int moisCourant, int anneeCourante) {
		if(moisCourant+1 > 11) {
			moisCourant = 0;
			anneeCourante = anneeCourante+1;
		} else {
			moisCourant = moisCourant+1;
		}
		Agenda.view.creerListeJoursDuMois(moisCourant,anneeCourante);
	}

	/**
	 * Affiche la semaine qui précède.
	 * @param semaineCourante La semaine sur laquelle nous sommes
	 * @param anneeCourante L'année sur laquelle nous sommes
	*/
	private void reactionClicSemainePrecedante(int semaineCourante, int anneeCourante) {
		if(semaineCourante-1 <= 0) {
			semaineCourante = 52;
			anneeCourante = anneeCourante-1;
		} else {
			semaineCourante = semaineCourante-1;
		}
		Agenda.view.creerListeJoursDuneSemaine(semaineCourante, anneeCourante);
	}

	/**
	 * Affiche la semaine qui suit.
	 * @param semaineCourante La semaine sur laquelle nous sommes
	 * @param anneeCourante L'année sur laquelle nous sommes
	*/
	private void reactionClicSemaineSuivante(int semaineCourante, int anneeCourante) {
		GregorianCalendar calendrier = new GregorianCalendar();
		calendrier.set(Calendar.YEAR, anneeCourante);
		
		if(semaineCourante+1 > calendrier.getActualMaximum(Calendar.WEEK_OF_YEAR)) {
			semaineCourante = 1;
			anneeCourante = anneeCourante+1;
		} else {
			semaineCourante = semaineCourante+1;
		}
		Agenda.view.creerListeJoursDuneSemaine(semaineCourante, anneeCourante);
	}

	/**
	 * Affiche l'onglet "Jour" qui contient les heures de la journée.
	 * @param jourDuMoisCourant Numéro du jour du mois
	 * @param moisCourant Numéro du mois dans l'année (compris entre 0 et 11)
	 * @param anneeCourante L'année dans laquelle se situe le jour
	*/
	private void reactionClicJourDUnMois(int jourDuMoisCourant, int moisCourant, int anneeCourante) {

		GregorianCalendar calendrier = new GregorianCalendar();
		calendrier.set(Calendar.MONTH, moisCourant);
		calendrier.set(Calendar.YEAR, anneeCourante);
		calendrier.set(Calendar.DAY_OF_MONTH, jourDuMoisCourant);

		Agenda.view.changerJour(calendrier.get(Calendar.DAY_OF_YEAR), anneeCourante);
		Agenda.view.getTabbedPane().setSelectedIndex(2);

		// On recupère les activités (s'il y en a) de ce jour
		GregorianCalendar dateDebut = new GregorianCalendar(anneeCourante, moisCourant, jourDuMoisCourant, 0, 0, 0);
		GregorianCalendar dateFin = new GregorianCalendar(anneeCourante, moisCourant, jourDuMoisCourant, 23, 59, 59);
		
		// On remet à jour le modèle de la table
		TableModelJour modelTableDesHeures = new TableModelJour();

		// On ajoute les activités
		ArrayList<Activity> listeActivite = Agenda.engine.getListeActivity(dateDebut, dateFin);
		Iterator it = listeActivite.iterator();
		Activity act;
		while(it.hasNext()) {
			act = (Activity) it.next();
			modelTableDesHeures.setValueAt(act.getDateDebut(), act.getDateFin(), dateDebut, act.getIntitule());
		}

		Agenda.view.getAgendaViewJour().getTableDesHeures().setModel(modelTableDesHeures);
	}

	/**
	 * Dans l'onglet "Jour", on passe au jour précédant.
	 * @param jour Numéro du jour du mois courant
	 * @param mois Numéro du mois (compris entre 0 et 11) courant
	 * @param annee L'année courante qui va avec le jour et le mois
	*/
	private void reactionClicJourPrecedant(int jourDuMois, int mois, int annee) {
		// On recupère le jour "courant"
		GregorianCalendar calendrier = new GregorianCalendar();

		calendrier.set(Calendar.YEAR,annee);
		// Le mois est compris entre 0 et 11
		calendrier.set(Calendar.MONTH,(mois-1));
		calendrier.set(Calendar.DAY_OF_MONTH,jourDuMois);

		// Ainsi, on obtient le numéro du jour de l'année
		int jour = calendrier.get(Calendar.DAY_OF_YEAR);

		if(jour-1 < 0) {
			annee = annee-1;
			calendrier.set(Calendar.YEAR,annee-1);
		}

		jour = jour-1;
		Agenda.view.changerJour(jour, annee);
		calendrier.set(Calendar.DAY_OF_YEAR,jour);

		// On recupère les activités (s'il y en a) de ce jour
		GregorianCalendar dateDebut = new GregorianCalendar(calendrier.get(Calendar.YEAR), calendrier.get(Calendar.MONTH), calendrier.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		GregorianCalendar dateFin = new GregorianCalendar(calendrier.get(Calendar.YEAR), calendrier.get(Calendar.MONTH), calendrier.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
		
		// On remet à jour le modèle de la table
		TableModelJour modelTableDesHeures = new TableModelJour();

		// On ajoute les activités
		ArrayList<Activity> listeActivite = Agenda.engine.getListeActivity(dateDebut, dateFin);
		Iterator it = listeActivite.iterator();
		Activity act;
		while(it.hasNext()) {
			act = (Activity) it.next();
			modelTableDesHeures.setValueAt(act.getDateDebut(), act.getDateFin(), dateDebut, act.getIntitule());
		}

		Agenda.view.getAgendaViewJour().getTableDesHeures().setModel(modelTableDesHeures);
	}

	/**
	 * Dans l'onglet "Jour", on passe au jour suivant.
	 * @param jour Numéro du jour du mois
	 * @param mois Numéro du mois (compris entre 0 et 11)
	 * @param annee L'année qui va avec le jour et le mois
	*/
	private void reactionClicJourSuivant(int jourDuMois, int mois, int annee) {
		// On recupère le jour "courant"
		GregorianCalendar calendrier = new GregorianCalendar();

		calendrier.set(Calendar.YEAR,annee);
		// Le mois est compris entre 0 et 11
		calendrier.set(Calendar.MONTH,(mois-1));
		calendrier.set(Calendar.DAY_OF_MONTH,jourDuMois);

		// Ainsi, on obtient le numéro du jour de l'année
		int jour = calendrier.get(Calendar.DAY_OF_YEAR);

		int maxJourDeAnnee = calendrier.getActualMaximum(Calendar.DAY_OF_YEAR);

		if(jour+1 > maxJourDeAnnee) {
			annee = annee+1;
		}
		jour = jour+1;
		Agenda.view.changerJour(jour, annee);
		calendrier.set(Calendar.DAY_OF_YEAR,jour);

		// On recupère les activités (s'il y en a) de ce jour
		GregorianCalendar dateDebut = new GregorianCalendar(calendrier.get(Calendar.YEAR), calendrier.get(Calendar.MONTH), calendrier.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		GregorianCalendar dateFin = new GregorianCalendar(calendrier.get(Calendar.YEAR), calendrier.get(Calendar.MONTH), calendrier.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
		
		// On remet à jour le modèle de la table
		TableModelJour modelTableDesHeures = new TableModelJour();

		// On ajoute les activités
		ArrayList<Activity> listeActivite = Agenda.engine.getListeActivity(dateDebut, dateFin);
		Iterator it = listeActivite.iterator();
		Activity act;
		while(it.hasNext()) {
			act = (Activity) it.next();
			modelTableDesHeures.setValueAt(act.getDateDebut(), act.getDateFin(), dateDebut, act.getIntitule());
		}

		Agenda.view.getAgendaViewJour().getTableDesHeures().setModel(modelTableDesHeures);
	}
}
